﻿using System;
using System.IO;

public class SocketBuffer
{
    private byte[] headByte;
    private byte headLength = 6;

    private byte[] allRecvData;//接受到的数据
    private int allDatalenght = 0;
    //当前接收到多少数据
    private int curRecvLength = 0;

    public SocketBuffer(byte tempHeadLenght, CallBackRecvOver tmpOverBack)
    {
        headLength = tempHeadLenght;
        headByte = new byte[headLength];
        callBackRecvOver = tmpOverBack;
    }

    public void RecvByte(byte[] recvByte, int realLength)
    {
        if (realLength <= 0) return;

        //当前接受的小于头的长度
        if (curRecvLength < headByte.Length)
        {
            RecvHead(recvByte, realLength);
        }
        else
        {
            //接受的总长度
            int tmpLenght = curRecvLength + realLength;

            if (tmpLenght == allDatalenght)
            {
                //刚刚好相等的情况
                RecvOneAll(recvByte, realLength);
            }
            else if (tmpLenght > allDatalenght)
            {
                //接受的数据比这个消息长
                RecvLarger(recvByte, realLength);
            }
            else if (tmpLenght < allDatalenght)
            {
                //body不全
                RecvSmall(recvByte, realLength);
            }
        }
    }

    private void RecvLarger(byte[] recbyte, int realLength)
    {
        int tmpLength = allDatalenght - curRecvLength;
        Buffer.BlockCopy(recbyte, 0, allRecvData, curRecvLength, tmpLength);
        curRecvLength += realLength;

        RecvOneMsgOver();

        int remainLength = realLength - tmpLength;

        byte[] reaminByte = new byte[remainLength];
        Buffer.BlockCopy(recbyte, tmpLength, reaminByte, 0, remainLength);

        RecvByte(reaminByte, remainLength);
    }
    private void RecvSmall(byte[] recbyte, int realLength)
    {
        Buffer.BlockCopy(recbyte, 0, allRecvData, curRecvLength, realLength);
        curRecvLength += realLength;
    }

    private void RecvOneAll(byte[] recbyte, int realLength)
    {
        Buffer.BlockCopy(recbyte, 0, allRecvData, curRecvLength, realLength);
        curRecvLength += realLength;
        RecvOneMsgOver();
    }

    private void RecvHead(byte[] recbyte, int realLenght)
    {
        //差多少个自己才能组成头
        int tmpReal = headByte.Length - curRecvLength;
        //现在接受的和已经接受的总长度多少
        int temlength = curRecvLength + realLenght;

        //总长度小于头
        if (temlength < headByte.Length)
        {
            Buffer.BlockCopy(recbyte, 0, headByte, curRecvLength, realLenght);
            curRecvLength += realLenght;
        }
        else
        {
            Buffer.BlockCopy(recbyte, 0, headByte, curRecvLength, tmpReal);
            curRecvLength += tmpReal;//头部已经凑齐了

            allDatalenght = BitConverter.ToInt32(headByte, 0) + headLength;

            allRecvData = new byte[allDatalenght];//body+head;
            // allrecvData 已经包含头部了
            Buffer.BlockCopy(headByte, 0, allRecvData, 0, headLength);

            int tmpRemin = realLenght - tmpReal;
            //是否recbyte是否还有数据
            if (tmpRemin > 0)
            {
                byte[] tmpByte = new byte[tmpRemin];
                //剩下的自己交给tmpbyte;
                Buffer.BlockCopy(recbyte, tmpRemin, tmpByte, 0, tmpRemin);

                RecvByte(tmpByte, tmpRemin);
            }
            else
            {

            }
        }
    }

    #region recv over back to

    public delegate void CallBackRecvOver(byte[] alldata);

    CallBackRecvOver callBackRecvOver;


    private void RecvOneMsgOver()
    {
        if (callBackRecvOver != null)
        {
            callBackRecvOver(allRecvData);
        }

        curRecvLength = 0;
        allDatalenght = 0;
        allRecvData = null;


    }

    #endregion
}
